#ifndef GEN_OP_HPP
#define GEN_OP_HPP
/**
 * @file   gen_op.hpp
 * @author Kimmo Luoma <kimmo@PHOTON3>
 * @date   Thu Oct 18 13:31:21 2012
 * 
 * @brief  Base class for operators that defines common functionality
 * 
 * 
 */
#include "RefBase.hpp"
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <iostream>
using namespace boost::numeric::ublas;

enum ACTS {COIN,SITE};
namespace QuantumWalk{
  class gen_op:virtual public RefBase{
  public:
    typedef Ref<gen_op> ptr_t;
    virtual ~gen_op()=0;
    virtual ptr_t pointer() = 0 ;
    gen_op():dimV_(0),dimD_(0){};
    gen_op(int dimD, int dimV):dimV_(dimV),dimD_(dimD){};
    int two_to_one(int j,int v){
      if(j<0||v<0){
	std::cerr<<"Indices can not be negative"<<std::endl;
	exit(1);
      }

      if(j>=dimD_ || v>= dimV_){
	std::cerr<<"Indices can not be larger than dimensions"<<std::endl;
	exit(1);
      }
      
      return j*dimV_+v;
    };
    vector<int> one_to_two(int k){
      if(k<0){
	std::cerr<<"Indices can not be negative"<<std::endl;
	exit(1);
      }
      if(k>=dimV_*dimD_){
	std::cerr<<"Indices can not be larger than dimensions"<<std::endl;
	exit(1);
      }
      
      int j,v;
      j=k/dimV_;
      v=k % dimV_;
      //Check
      //k==j*dimV_+v
      vector<int> ret(2);
      ret[0]=j;
      ret[1]=v;
      return ret;
    };
    //gen_op(const &gen_op<T> g){dimV_=g.dimV_;dimD_=g.dimD_;};
  protected:
    int dimV_,dimD_;//Number of sites, number of internal degrees of freedom, respectively
  };
};

inline QuantumWalk::gen_op::~gen_op(){};
 
#endif
